home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 13300 / POF0 decoder source.7z / POF0.cpp next >
Encoding:
C/C++ Source or Header  |  2017-09-10  |  6.7 KB  |  259 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdint.h>
  5.  
  6. uint32_t toBigEndian_word(uint32_t num)
  7. {
  8.     uint32_t b0 = (num & 0x000000ff) << 24u;
  9.     uint32_t b1 = (num & 0x0000ff00) << 8u;
  10.     uint32_t b2 = (num & 0x00ff0000) >> 8u;
  11.     uint32_t b3 = (num & 0xff000000) >> 24u;
  12.  
  13.     uint32_t res = b0 | b1 | b2 | b3;
  14.     return res;
  15. }
  16.  
  17. uint16_t toBigEndian_halfword(uint16_t num)
  18. {
  19.     uint16_t b0 = (num & 0x000000ff) << 8u;
  20.     uint16_t b1 = (num & 0x0000ff00) >> 8u;
  21.  
  22.     uint16_t res = b0 | b1;
  23.     return res;
  24. }
  25. int lw(FILE * stream, int address, short offset)
  26. {
  27.     fseek(stream, address + offset, SEEK_SET);
  28.     int res;
  29.     fread(&res, 1, 4, stream);
  30.     return res;
  31. }
  32.  
  33. unsigned char lbu(FILE * stream, int address, short offset)
  34. {
  35.     fseek(stream, address + offset, SEEK_SET);
  36.     unsigned char res;
  37.     fread(&res, 1, 1, stream);
  38.     return res;
  39. }
  40.  
  41. unsigned short lhu(FILE * stream, int address, short offset)
  42. {
  43.     fseek(stream, address + offset, SEEK_SET);
  44.     unsigned short res;
  45.     fread(&res, 1, 2, stream);
  46.     return res;
  47. }
  48.  
  49. void sw(FILE *stream, int address, short offset, int value)
  50. {
  51.     fseek(stream, address + offset, SEEK_SET);
  52.     fwrite(&value, 1, 4, stream);
  53. }
  54.  
  55. void sb(FILE *stream, int address, short offset, char value)
  56. {
  57.     fseek(stream, address + offset, SEEK_SET);
  58.     fwrite(&value, 1, 1, stream);
  59. }
  60.  
  61. void process_POF0(FILE * f, char filename[], int POF0_offset=0x1D2E0, int POF0_size=0x0288, bool is_little=true)
  62. {
  63.     int at;
  64.     int v1;
  65.     int a0=POF0_offset; // The Rock's POF0
  66.     int a1=POF0_size; // Size of POF0
  67.     int a2=0x08; // YOBJ size + 4
  68.     int a3; // Start of POF0 String
  69.     int t0;
  70.     int t1;
  71.     int t2;
  72.     int t3;
  73.     int t4;
  74.  
  75.     FILE * yobj_file = f;
  76.     char new_filename[255];
  77.     strcpy(new_filename, filename);
  78.     strcat(new_filename, ".decrypted");
  79.     FILE * output_file = fopen(new_filename, "wb+");
  80.  
  81.     // Get size of yobj
  82.     fseek(yobj_file, 0L, SEEK_END);
  83.     int yobj_size = ftell(yobj_file);
  84.  
  85.     char * buffer = (char *) malloc(yobj_size);
  86.     rewind(yobj_file);
  87.     fread(buffer, 1, yobj_size, yobj_file);
  88.  
  89.     fseek(output_file, 0L, SEEK_SET);
  90.  
  91.     fwrite(buffer, 1, yobj_size, output_file);
  92.  
  93.     free(buffer);
  94.  
  95.     while (true)
  96.     {
  97.         t0 = a0 + a1;
  98.         at = a0 < t0;
  99.         if (!at)
  100.             break;
  101.         t1 = a2;
  102.         a1 = 0x80;
  103.         v1 = 0x40;
  104.         a3 = 0xC0;
  105.         t3 = lbu(output_file, a0, 0x00);
  106.         while (true)
  107.         {
  108.             //printf("Offset: %.8X\n", a0);
  109.             t2 = t3 & 0xC0;
  110.             //printf("%.8X %.2X\n", a0, t3);
  111.             if (t2 == a3)
  112.             {
  113.                 unsigned short sp;
  114.                 sp = 0;
  115.                 //*(i+3) =t3;
  116.                 sp |= (t3 & 0xFF) << 24;
  117.                 // case 3
  118.                 t4 = lbu(output_file, a0, 0x03);
  119.                 t3 = lbu(output_file, a0, 0x02);
  120.                 t2 = lbu(output_file, a0, 0x01);
  121.  
  122.                 //*(i+0)= t4;
  123.                 //*(i+1)= t3;
  124.                 //*(i+2)= t2;
  125.                 sp |= t4 & 0xFF;
  126.                 sp |= (t3 & 0xFF) << 8;
  127.                 sp |= (t2 & 0xFF) << 16;
  128.                 t2 = sp;
  129.  
  130.                 if (!is_little)
  131.                     t2 = toBigEndian_word(t2);
  132.                 a0 += 4;
  133.                 t2 <<= 2;
  134.                 t2 >>= 2;
  135.                 t2 <<= 2;
  136.                 a2 += t2;
  137.                 t2 = lw(output_file, a2, 0x00);
  138.                 if (!is_little)
  139.                     t2 = toBigEndian_word(t2);
  140.                 t2 += t1;
  141.                 // little Endian
  142.                 if (!is_little)
  143.                     t2 = toBigEndian_word(t2);
  144.                 sw(output_file, a2, 0x00, t2);
  145.                 if (!is_little)
  146.                     t2 = toBigEndian_word(t2);
  147.             }
  148.             else if (t2 == a1)
  149.             {
  150.                 // case 2
  151.                 t2 = lbu(output_file, a0, 0x01);
  152.                 unsigned short  sp;
  153.                 sp = 0;
  154.                 //*(i+1)=t3;
  155.                 //*(i+0)=t2;
  156.                 sp |= (t3 & 0xFF) << 8;
  157.                 sp |= t2 & 0xFF;
  158.                 t2 = sp;
  159.                 if (!is_little)
  160.                     t2 = toBigEndian_halfword(t2);
  161.  
  162.                 a0 += 2;
  163.                 t2 &= 0x3FFF;
  164.                 t2 <<= 2;
  165.                 a2 += t2;
  166.                 t2 = lw(output_file, a2, 0x00);
  167.                 if (!is_little)
  168.                     t2 = toBigEndian_word(t2);
  169.                 t2 += t1;
  170.                 // little Endian
  171.                 if (!is_little)
  172.                     t2 = toBigEndian_word(t2);
  173.                 sw(output_file, a2, 0x00, t2);
  174.                 if (!is_little)
  175.                     t2 = toBigEndian_word(t2);
  176.             }
  177.             else if (t2 == v1)
  178.             {
  179.                 // case 1
  180.  
  181.                 t2 = t3 & 0x3F;
  182.  
  183.                 t2 <<= 2;
  184.  
  185.  
  186.                 a2 += t2;
  187.  
  188.                 t2 = lw(output_file, a2, 0x00);
  189.                 if (!is_little)
  190.                     t2 = toBigEndian_word(t2);
  191.                 //printf("%.8X\n", t2);
  192.                 a0 += 1;
  193.                 t2 += t1;
  194.  
  195.                 if (!is_little)
  196.                     t2 = toBigEndian_word(t2);
  197.  
  198.                 sw(output_file, a2, 0x00, t2);
  199.                 if (!is_little)
  200.                     t2 = toBigEndian_word(t2);
  201.             }
  202.             else
  203.                 a0 += 1;
  204.  
  205.             // 0x0890D2B8
  206.             t2 = a0 < t0;
  207.             if (t2)
  208.             {
  209.                 t3 = lbu(output_file, a0, 0x0);
  210.                 continue;
  211.             }
  212.             break;
  213.         }
  214.         break;
  215.     }
  216.  
  217.  
  218.     fclose(output_file);
  219.     return;
  220.  
  221. }
  222. int main(int argc, char * argv[])
  223. {
  224.     char filename[255];
  225.     int POF0_offset;
  226.     int POF0_size;
  227.     char byteorder[8];
  228.     printf("POF0 decoder by eatrawmeat391\n");
  229.  
  230.     if (argc != 4)
  231.     {
  232.         printf("Usage: POF0.exe infile POF0_offset POF0_size");
  233.         return 0;
  234.     }
  235.  
  236.     strcpy(filename, argv[1]);
  237.     POF0_offset = (int) strtol(argv[2], NULL, 16);
  238.     POF0_size   = (int) strtol(argv[3], NULL, 16);
  239.     //strcpy(byteorder, argv[4]);
  240.     bool is_little;
  241.     //if (strcmpi(byteorder, "little") == 0)
  242.         //is_little = true;
  243.     //else
  244.         //is_little = false;
  245.     is_little = true;
  246.     FILE * yobj_file = fopen(filename, "rb");
  247.     if (!yobj_file)
  248.     {
  249.         printf("Cannot open this file.\n");
  250.         return 0;
  251.     }
  252.     process_POF0(yobj_file, filename, POF0_offset, POF0_size, is_little);
  253.     fclose(yobj_file);
  254.  
  255.     printf("POF0 successfully decoded, the file %s.decrypted has been created.\n");
  256.     getchar();
  257.     return 0;
  258. }
  259.